﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace AgileFx.MVC.PerformanceTools
{
    public class TraceContext
    {
        public string EventId { get; private set; }

        public TraceContext()
        {
            EventId = Guid.NewGuid().ToString();
        }

        public LogEntry WriteToLog(string type, string data)
        {
            var entry = new LogEntry(EventId, type, data);
            Write(entry);
            return entry;
        }

        public LogEntry WriteToLog(string type, string data, string parentId)
        {
            var entry = new LogEntry(EventId, type, data, parentId);
            Write(entry);
            return entry;
        }

        private void Write(LogEntry entry)
        {
            LogWriter.Write(entry);

            //Write Stack Trace

            StackTrace stackTrace = new StackTrace();
            StackFrame[] stackFrames = stackTrace.GetFrames();

            var stackDetails = new List<string>();
            foreach (var frame in stackFrames)
            {
                var method = frame.GetMethod();
                if (method.DeclaringType != null)
                {
                    var declaringType = method.DeclaringType.FullName;
                    if (PerformanceSpy.LogStackFramesFromNamespaces.Any(ns => declaringType.StartsWith(ns))
                        && !PerformanceSpy.ExcludeStackFramesFromNamespaces.Any(ns => declaringType.StartsWith(ns)))
                    {
                        stackDetails.Add(declaringType + ":" + method.Name);
                    }
                }
            }

            if (stackDetails.Count > 0)
            {
                var stackFrameEntry = new LogEntry(EventId, "StackTrace", string.Join(", ", stackDetails.ToArray()), entry.Id);
                LogWriter.Write(stackFrameEntry);
            }
        }
    }
}
